import { AnyObj, VmTyp } from './types'
import Observer from './Observer'
import Complier from './Complier'

interface VueOptions {
    el: string | HTMLElement,
    data: AnyObj | (() => AnyObj),
    methods: AnyObj
}
export default class Vue implements VmTyp {
    $el: HTMLElement
    $data: AnyObj
    [key:string]: any
    constructor(options: VueOptions) {
        let { el, data, methods } = options;
        if (typeof el === 'string') {
            this.$el = document.getElementById(el) || document.body
        } else {
            this.$el = el
        }
        let d = typeof data === 'function' ? data() : data

        this.$data = d

        //将方法挂载再vue上
        Object.keys(methods).forEach(f => {
            this[f] = methods[f]
        })

        //将data挂载到vue,并转换为存取器模式
        this.__proxyDate(this.$data)

        //将数据转换为响应式
        new Observer(this.$data)

        //编译模板
        new Complier(this)
    }
    __proxyDate(data: AnyObj) {
        Object.keys(data).forEach(key => {
            Object.defineProperty(this, key, {
                enumerable: true,
                configurable: true,
                get() {
                    return data[key]
                },
                set(nVal) {
                    if (data[key] !== nVal) {
                        data[key] = nVal
                    }
                }
            })
        })
    }
}